TODO LIST
前言概念
recyclerView 就是一個能夠呈現像是清單列的一種 layout,每個 item 要放怎樣的格式必須要再另外的定義,透過 recyclerViewAdapter 去實作出來。在這個專案裡面,打算實作一個 TODO 清單,可以增加說明文字以及圖片,並且讓新增的這筆資料顯示在 recyclerView 上面,這篇先示範處理顯示文字 TextView 的部分。recyclerView 文章參考
將 recyclerViewAdapter 實作出來
這是我學習 adapter 的第一個範本,那時就在想,到底什麼叫做 adapter,為何 adapter 要實作那麼多 function?現在回來整理一次筆記時,更能體會它的含義了。程式裡面的資料,要把他們呈現到畫面的這個環節,就需要透過 adapter 去達成,因為每個 layout 都有他呈現的方式(清單式、navigation 的樣式 ... 等等),而只要告訴 adapter 說現在的資料有哪些,以及一些該 layout 定好的規則需要去做填寫 (每個 layout 有可能有不同規則),背後就會自動將資料通通畫到畫面上囉!
在這個 recyclerViewAdapter 裡面,需要告訴他每個 item 要長怎樣 (需要回傳一個 View.Holder),這是這個 layout 的特性,如果是 BaseAdapter 就不需要做到這件事情。以下是 recyclerViewAdapter 部分程式碼
private var noteList = mutableListOf<Holder.Datas>()
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout._4_item_note, viewGroup, false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return noteList.size
}
override fun onBindViewHolder(viewHolder: MyViewHolder, position: Int) {
viewHolder.bind(noteList[position])
}
class MyViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val tvNote = view.tv_note
fun bind(newList: Holder.Datas) {
tvNote.text = newList.text
}
}
fun update(newList: MutableList<Holder.Datas>) {
noteList = newList
notifyDataSetChanged()
}
當資料有變動的時候,記得要呼叫 notifyDataSetChanged ,畫面才會改變唷!
將編輯頁面的資料回傳回主畫面
這個專案的新增文字清單,是進到一個新的 fragment 裡面做新增並且按送出,才會返回回主清單頁面。在轉換 Activity 裡面可以透過 ActivityResult 去接取別的 Activity 傳進的資料,那 fragment 呢?
在 fragment 裡面,是透過 argument 做傳遞的。今天在編輯頁面按下送出的時候,直接把新增的文字做成一個 bundle,塞回給主畫面,這時主畫面再使用 getArguments() 去做接取,就會接到啦!
// At edit fragment
//
val NEW_DATA = "new"
args.putString(NEW_DATA, view.input_data.text.toString())
val todoList = fragmentManager!!.findFragmentByTag("todoList")
todoList!!.arguments = args
// At main fragment
val NEW_DATA = "new"
if(arguments != null){
val newTxt = arguments?.getString(NEW_DATA)
holderList.add(Holder.Datas(null, newTxt))
recyclerAdapter.update(holderList)
}
因為在切回 main 時會進入 onCreateView ,所以上述收參數的部分寫在 onCreateView 即可。
收不到回傳回來的參數
一開始我使用了 savedInstanceState 去做接收,但怎麼看都沒有正確地收到參數,很怪,後來才知道應該要使用 getArguments() ,savedInstanceState 應該是用在 Activity 等級的切換,需要進入 onSavedInstanceState 的那種才算,而這邊因為只是 fragment 的切換,Activity 根本沒有 onDestroy。
明明新增了一筆資料,為什麼畫面沒有更新?
原先以為在 list 後面新增一筆資料之後,畫面就會更新了,但是其實必須要告訴 adapter 說,我現在的資料已經更新了,畫面要重畫一次,而這個動作就是呼叫 notifyDataSetChanged 就可以解決囉!